/** 创建一个嵌套递归的 cypress 链式实例
 * 注意 cypress 的异步函数永远无法与 promise 和 async await 一起工作
 * https://docs.cypress.io/faq/questions/using-cypress-faq#Can-I-use-the-new-ES7-async-await-syntax
 *
 * @param options.chainable   创建的一个 cypress 链式实例 的函数
 * @param options.maxTryCount 最多需等待的次数
 * @param options.handler  每次等待成功后执行的回调，若返回 true 则提前结束所有等待
 * @param options.onSuccess 所有链式调用都成功后执行的回调
 * @param options.onMaxCount 超出最大执行次数后的回调
 * */
export function createChainInstance<T>(options: {
  getChainInstance: () => Cypress.Chainable
  maxTryCount: number
  handler: (data: T) => boolean
  onSuccess?: () => void
  onMaxCount?: () => void
}) {
  const { getChainInstance, maxTryCount, handler, onSuccess, onMaxCount } = options
  let tryCount = 0
  function run() {
    getChainInstance().then((data: T) => {
      if (tryCount === maxTryCount) {
        onMaxCount?.()
        return
      }
      tryCount += 1
      if (handler(data)) {
        onSuccess?.()
      } else {
        run()
      }
    })
  }
  run()
}
